package com.seleniti.enpareja.android.ui.view;

import org.ioc.commons.impl.android.ui.HasEnabledWrapper;
import org.ioc.commons.impl.android.ui.HasLoaderWrapper;
import org.ioc.commons.impl.android.ui.HasValueWrapper;
import org.ioc.commons.impl.android.ui.HasVisibilityWrapper;
import org.ioc.commons.ui.HasEnabled;
import org.ioc.commons.ui.HasLoader;
import org.ioc.commons.ui.HasValue;
import org.ioc.commons.ui.HasVisibility;
import org.ioc.commons.ui.features.Info;
import org.ioc.commons.ui.impl.HasEnabledAdapter;
import org.ioc.commons.ui.impl.HasValueAdapter;
import org.ioc.commons.ui.impl.HasVisibilityAdapter;
import org.ioc.commons.ui.impl.OnChangeCommand;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.TextView;

import com.seleniti.enpareja.android.R;
import com.seleniti.enpareja.android.ui.widget.InfoInlineWidget;
import com.seleniti.enpareja.controller.control.place.EnParejaPlace;
import com.seleniti.enpareja.controller.ui.view.LoginView;
import com.seleniti.enpareja.controller.ui.view.LoginView.Action;
import com.seleniti.enpareja.controller.ui.view.LoginView.Event;
import com.seleniti.enpareja.controller.ui.view.LoginView.Operation;
import com.seleniti.enpareja.controller.ui.view.LoginView.Presenter;
import com.seleniti.enpareja.controller.ui.view.LoginViewPresenter;

public class LoginViewWidget extends EnParejaBaseView<Event, Operation, Action, Presenter> implements LoginView {

	private TextView loginName;
	private TextView loginPassword;
	private CheckBox rememberMe;
	private Button btnLogin;
	private ProgressBar loader;
	private InfoInlineWidget loginFailed;
	private Button btnAndroidLogin;
	private Button btnSignUp;
	private EnParejaPlace goToPlaceWhenOk;
	private Button btnSolveNoPasswordSet;

	public LoginViewWidget() {
		super(false);
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.setRetainInstance(true);
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		this.presenter = new LoginViewPresenter(this, eventbus, operationManager, actionController);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.login_view, container, false);
		this.loginName = (TextView) view.findViewById(R.id.loginName);
		this.loginPassword = (TextView) view.findViewById(R.id.loginPassword);
		this.rememberMe = (CheckBox) view.findViewById(R.id.rememberMe);
		this.btnLogin = (Button) view.findViewById(R.id.btnLogin);
		this.loader = (ProgressBar) view.findViewById(R.id.loader);
		this.loginFailed = (InfoInlineWidget) view.findViewById(R.id.loginFailed);
		this.btnAndroidLogin = (Button) view.findViewById(R.id.btnAndroidLogin);
		this.btnLogin = (Button) view.findViewById(R.id.btnLogin);
		this.btnSignUp = (Button) view.findViewById(R.id.btnSignUp);
		this.btnSolveNoPasswordSet = (Button) view.findViewById(R.id.btnSolveNoPasswordSet);
		this.btnSolveNoPasswordSet.setText(Html.fromHtml(getString(R.string.underlined_how_can_i_fix_it))); 

		this.btnLogin.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				tryLogin();
			}
		});

		this.btnAndroidLogin.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				goToGoogleLoginView();
			}
		});

		this.btnSignUp.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				goToSignUpView();
			}
		});

		this.btnSolveNoPasswordSet.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				presenter.onGoToSolveNoPasswordSetView();
			}
		});
		
		return view;
	}

	@Override
	public HasValue<String> loginName() {
		return HasValueWrapper.from(loginName, this);
	}

	@Override
	public HasValue<String> loginPassword() {
		return HasValueWrapper.from(loginPassword, this);
	}

	@Override
	public HasValue<Boolean> rememberMe() {
		return HasValueWrapper.from(rememberMe, this);
	}

	@Override
	public Info loginFailed() {
		return this.loginFailed;
	}

	@Override
	public void tryLogin() {
		hiddenKeyboard(loginPassword);
		this.presenter.onTryLogin();
	}

	private void hiddenKeyboard(View v) {
		if (v == null) {
			return;
		}
		InputMethodManager keyboard = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
		keyboard.hideSoftInputFromWindow(v.getWindowToken(), 0);
	}

	@Override
	public HasLoader tryingLogin() {
		return HasLoaderWrapper.fromVisible(loader, this);
	}

	@Override
	public HasEnabled actionsEnabled() {
		return HasEnabledAdapter.forField("actionsEnabled", this).onChange(new OnChangeCommand<Boolean>() {

			@Override
			public void execute(Boolean enabled) {
				HasEnabledWrapper.setEnabled(enabled, btnLogin);
			}
		});
	}

	@Override
	public HasValue<Board> board() {
		/*
		 * In Android implementation there is no boards. It doesn't take effect.
		 */
		return HasValueAdapter.forField("board", this);
	}

	@Override
	public HasVisibility downloadAppButtonVisibility() {
		/*
		 * In Android implementation there is no download app button
		 */
		return HasVisibilityAdapter.forField("downloadAppButtonVisiblity", this);
	}

	@Override
	public void goToSignUpView() {
		this.presenter.onGoToSignUpView();
	}

	@Override
	public void goToGoogleLoginView() {
		this.presenter.onGoToGoogleLoginView();
	}

	@Override
	public void focusLoginFailed() {
		new Handler().post(new Runnable() {
			@Override
			public void run() {
				ViewParent p = getView().getParent();

				while (!(p instanceof ScrollView) && (p = p.getParent()) != null)
					;

				if (p instanceof ScrollView) {
					((ScrollView) p).scrollTo(0, loginFailed.getBottom());
				}
			}
		});
	}

	@Override
	public void goToDownloadAppView() {
		this.presenter.onGoToDownloadAppView();
	}

	@Override
	public void setGoToPlaceWhenOk(EnParejaPlace goWhenOk) {
		this.goToPlaceWhenOk = goWhenOk;
	}

	@Override
	public EnParejaPlace getGoToPlaceWhenOk() {
		return this.goToPlaceWhenOk;
	}

	@Override
	public HasVisibility infoSolveNoPasswordSet() {
		return HasVisibilityWrapper.from(btnSolveNoPasswordSet, this);
	}
}
